package com.atwulidun.stack;

import java.util.Scanner;

public class SingleLinkedListStackDemo {
    public static void main(String[] args) {
        SingleLinkedListStack stack = new SingleLinkedListStack(5);
        Scanner scanner = new Scanner(System.in);
        String key = "";
        boolean loop = true;
        while (loop) {
            System.out.println("show：显示栈");
            System.out.println("exit：退出栈");
            System.out.println("push：进栈");
            System.out.println("pop：出栈");
            System.out.println("请输入：");
            key = scanner.next();
            switch (key) {
                case "show":
                    try {
                        stack.list2();
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case "exit":
                    scanner.close();
                    loop = false;
                    System.out.print("程序退出！");
                    break;
                case "push":
                    System.out.println("请输入入栈整数：");
                    int value = scanner.nextInt();
                    stack.push(value);
                    break;
                case "pop":
                    try {
                        System.out.println("出栈数据为：" + stack.pop());
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
            }
        }
    }
}

class SingleLinkedListStack {
    private StackNode head = new StackNode(0);
    private int maxSize = 0;

    public SingleLinkedListStack(int maxSize) {
        this.maxSize = maxSize;
    }

    public StackNode getHead() {
        return head;
    }

    public boolean isEmpty() {
        return head.getNext() == null;
    }

    public boolean isFull() {
        return size() == maxSize;
    }

    private int size() {
        StackNode temp = head.getNext();
        int count = 0;
        while (temp != null) {
            count++;
            temp = temp.getNext();
        }
        return count;
    }

    public void push(int value) {
        if (isFull()) {
            System.out.println("栈已经满了！！！");
            return;
        }
        StackNode temp = head;
        while (temp.getNext() != null) {
            temp = temp.getNext();
        }
        StackNode newNode = new StackNode(value);
        temp.setNext(newNode);
    }

    public int pop() {
        if (isEmpty()) {
            throw new RuntimeException("栈为空！");
        }
        StackNode temp = head;
        while (temp.getNext().getNext() != null) {
            temp = temp.getNext();
        }
        int value = temp.getNext().getValue();
        temp.setNext(null);
        return value;
    }

    // 打印时从链表的尾部开始打印，为了不与当前链表的数据搞混，因此再新建一个链表调用push方法
    public void list() {
        if (isEmpty()) {
            System.out.println("栈为空！");
            return;
        }
        StackNode temp = head.getNext();
        SingleLinkedListStack stack = new SingleLinkedListStack(maxSize);
        while (temp != null) {
            stack.push(temp.getValue());
            temp = temp.getNext();
        }
        StackNode temp1 = stack.getHead().getNext();
        while (temp1 != null) {
            temp1 = temp1.getNext();
        }
        while (!stack.isEmpty()) {
            System.out.println(stack.pop());
        }
    }

    // 用递归的方法打印链表
    public void list1(StackNode node) {
        if (isEmpty()) {
            System.out.println("栈为空！");
            return;
        }
        if (node == null) {
            return;
        }
        list1(node.getNext());
        System.out.println(node.getValue());
    }

    public void list2() {
        list1(head.getNext());
    }
}

class StackNode {
    private int value;
    private StackNode next;

    public StackNode(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public StackNode getNext() {
        return next;
    }

    public void setNext(StackNode next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return "StackNode{" +
                "value=" + value +
                '}';
    }
}

//class SingleLinkedListStack{
//    private StackNode head = new StackNode(Integer.MAX_VALUE);
//
//    public boolean isEmpty() {
//        return head.getNext() == null;
//    }
//
//    public void push(int num) {
//        StackNode temp = head;
//        while (temp.getNext() != null) {
//            temp = temp.getNext();
//        }
//        temp.setNext(new StackNode(num));
//    }
//
//    public int pop() {
//        if (isEmpty()) {
//            throw new RuntimeException("the stack is empty!");
//        }
//        StackNode tempStackNode = head;
//        while (tempStackNode.getNext().getNext() != null) {
//            tempStackNode = tempStackNode.getNext();
//        }
//        int temp = tempStackNode.getNext().getValue();
//        tempStackNode.setNext(null);
//        return temp;
//    }
//
//    public void list() {
//        if (isEmpty()) {
//            throw new RuntimeException("the stack is empty!");
//        }
//        recursiveList(head.getNext());
//    }
//
//    private void recursiveList(StackNode head) {
//        if (head == null) {
//            return;
//        }
//        recursiveList(head.getNext());
//        System.out.println(head.getValue());
//    }
//}
//
//class StackNode {
//    private int value;
//    private StackNode next;
//
//    public StackNode(int value) {
//        this.value = value;
//    }
//
//    public int getValue() {
//        return value;
//    }
//
//    public void setValue(int value) {
//        this.value = value;
//    }
//
//    public StackNode getNext() {
//        return next;
//    }
//
//    public void setNext(StackNode next) {
//        this.next = next;
//    }
//
//    @Override
//    public String toString() {
//        return "StackNode{" +
//                "value=" + value +
//                ", next=" + next +
//                '}';
//    }
//}